﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Silverlight.Navigation.Favorites;
using Silverlight.Navigation.History;
using Silverlight.Navigation.Mapping;

namespace Silverlight.Navigation.Controls
{
    public partial class NavigationToolbar : UserControl
    {
        #region Events

        public event EventHandler<NavigationEventArgs> Go;
        public event EventHandler GoBack;
        public event EventHandler GoForward;
        public event EventHandler ClearHistory;

        #endregion

        #region Fields

        private HistoryManager _historyManager;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the NavigationToolbar class.
        /// </summary>
        public NavigationToolbar()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Initializes a new instance of the NavigationToolbar class.
        /// </summary>
        /// <param name="historyManager">The history manager for the application.</param>
        /// <param name="favoritesManager">The favorites manager for the application.</param>
        public NavigationToolbar(HistoryManager historyManager, FavoritesManager favoritesManager)
            : this()
        {
            if (historyManager == null)
                throw new ArgumentNullException("historyManager");

            if (favoritesManager == null)
                throw new ArgumentNullException("favoritesManager");

            HistoryManager = historyManager;
            FavoritesManager = favoritesManager;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Whether or not the back button is enabled.
        /// </summary>
        public bool CanGoBack
        {
            get { return this.BackButton.IsEnabled; }
            set { this.BackButton.IsEnabled = value; }
        }

        /// <summary>
        /// Whether or not the forward button is enabled.
        /// </summary>
        public bool CanGoForward
        {
            get { return this.ForwardButton.IsEnabled; }
            set { this.ForwardButton.IsEnabled = value; }
        }

        /// <summary>
        /// The history manager for the application.
        /// </summary>
        public HistoryManager HistoryManager 
        {
            get { return _historyManager; }
            set
            {
                _historyManager = value;

                this.AddressBox.SelectionChanged -= AddressBox_SelectionChanged;
                this.AddressBox.ItemsSource = _historyManager.RecentUris;
                this.AddressBox.SelectionChanged += AddressBox_SelectionChanged;
            }
        }

        /// <summary>
        /// The favorites manager for the application.
        /// </summary>
        public FavoritesManager FavoritesManager { get; set; }

        /// <summary>
        /// Whether or not the toolbar is expanded.
        /// </summary>
        public bool IsExpanded
        {
            get { return this.NavExpander.IsExpanded; }
            set { this.NavExpander.IsExpanded = value; }
        }

        /// <summary>
        /// The current uri.
        /// </summary>
        public string CurrentUri
        {
            get 
            {
                if (this.AddressBox.SelectedItem != null && this.AddressBox.SelectedItem is string)
                    return (string)this.AddressBox.SelectedItem;
                else
                    return string.Empty;
            }
            set
            {
                this.AddressBox.SelectionChanged -= AddressBox_SelectionChanged;
                this.AddressBox.SelectedItem = value;
                this.AddressBox.SelectionChanged += AddressBox_SelectionChanged;
            }
        }

        #endregion

        #region Methods

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the selection changed event for the address box.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddressBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.AddressBox.SelectedItem != null && Go != null)
                Go(this, new NavigationEventArgs(this.CurrentUri));
        }

        /// <summary>
        /// Handles the click event for the back button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BackButton_Click(object sender, RoutedEventArgs e)
        {
            if (GoBack != null)
                GoBack(this, new EventArgs());
        }

        /// <summary>
        /// Handles the click event for the forward button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ForwardButton_Click(object sender, RoutedEventArgs e)
        {
            if (GoForward != null)
                GoForward(this, new EventArgs());
        }

        /// <summary>
        /// Handles the click event for the history button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HistoryButton_Click(object sender, RoutedEventArgs e)
        {
            History history = new History();
            history.HistoryManager = this.HistoryManager;
            history.Title = "History";
            history.Closed += new EventHandler(History_Closed);
            history.ClearHistory += new EventHandler(History_ClearHistory);
            history.Show();
        }

        /// <summary>
        /// Handles the clear history event of the history dialog.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void History_ClearHistory(object sender, EventArgs e)
        {
            this.HistoryManager.Clear();

            if (ClearHistory != null)
                ClearHistory(this, new EventArgs());
        }

        /// <summary>
        /// Handles the closed event of the History dialog box.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void History_Closed(object sender, EventArgs e)
        {
            if (sender is History)
            {
                History history = (History)sender;

                if (history.DialogResult.HasValue && history.DialogResult.Value && !(string.IsNullOrEmpty(history.SelectedUri)))
                {
                    if (this.Go != null)
                        Go(this, new NavigationEventArgs(history.SelectedUri));
                }
            }
        }

        /// <summary>
        /// Handles the click event for the favorites button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FavoritesButton_Click(object sender, RoutedEventArgs e)
        {
            Favorites favorites = new Favorites(this.FavoritesManager);
            favorites.Closed += new EventHandler(Favorites_Closed);
            favorites.Show();
        }

        /// <summary>
        /// Handles the closed event of the favorites control.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Favorites_Closed(object sender, EventArgs e)
        {
            if (sender is Favorites)
            {
                Favorites favorites = (Favorites)sender;

                if (favorites.DialogResult.HasValue && favorites.DialogResult.Value && favorites.SelectedFavoriteItem != null)
                {
                    if (this.Go != null)
                        Go(this, new NavigationEventArgs(favorites.SelectedFavoriteItem.Uri));
                }
            }
        }

        /// <summary>
        /// Handles the click event for the add to to favorites button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddToFavoritesButton_Click(object sender, RoutedEventArgs e)
        {
            AddToFavorites addToFavorites = new AddToFavorites(this.CurrentUri);
            addToFavorites.Closed += new EventHandler(AddToFavorites_Closed);
            addToFavorites.Show();
        }

        /// <summary>
        /// Handles the closed event of the add to favorites control.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddToFavorites_Closed(object sender, EventArgs e)
        {
            if (sender is AddToFavorites)
            {
                AddToFavorites addToFavorites = (AddToFavorites)sender;

                if (addToFavorites.DialogResult.HasValue && addToFavorites.DialogResult.Value &&
                    addToFavorites.FavoriteItem != null)
                    this.FavoritesManager.Add(addToFavorites.FavoriteItem);
            }
            
        }

        /// <summary>
        /// Handles the click event for the set as home page button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetAsHomePageButton_Click(object sender, RoutedEventArgs e)
        {
            this.FavoritesManager.HomePage = new FavoriteItem { Name = "Home Page", Uri = this.CurrentUri };
        }

        /// <summary>
        /// Handles the click event for the use default home page button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UseDefaultHomePage_Click(object sender, RoutedEventArgs e)
        {
            this.FavoritesManager.HomePage = null;
        }

        #endregion
    }

    /// <summary>
    /// Event args for navigation events.
    /// </summary>
    public class NavigationEventArgs : EventArgs
    {
        #region Constructors

        /// <summary>
        /// Instantiates a new instance of the NavigationEventArgs class.
        /// </summary>
        /// <param name="uri"></param>
        public NavigationEventArgs(string uri)
        {
            Uri = uri;
        }

        #endregion

        #region Properties

        /// <summary>
        /// The uri to navigate to.
        /// </summary>
        public string Uri { get; set; }

        #endregion
    }
}
